#!/usr/bin/evn python

import wsgiref.handlers
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.api import urlfetch


from models import *
from ptzmodels import *
from common.constants import *

import string

webapp.template.register_template_library('common.customtags')

"""
Insert a bunch of correspondences and meshes into the DB.
"""
class Insert(webapp.RequestHandler):
    def post(self):
        from common.commonDB import addScene, addCorrespondence, addMesh
        import common.meshwriter
        import calibrate
        import urllib2
        from google.appengine.api import users, memcache
        
        user = users.get_current_user()
        if not user:
            username = ''
        else:
            username = user.nickname()
        
        logInURL = users.create_login_url(self.request.url)
        logOutURL = users.create_logout_url(self.request.url)

        # read the input.
        imageUs = self.request.get('imageUs').split(';')
        imageVs = self.request.get('imageVs').split(';')
        latitudes = self.request.get('latitudes').split(';')
        longitudes = self.request.get('longitudes').split(';')
        altitudes = self.request.get('altitudes').split(';')
        triangleIndices = self.request.get('triangleIndices').split(';')

        allImageUs = []
        allImageVs = []
        allLatitudes = []
        allLongitudes = []
        allAltitudes = []
        allTriangleIndices = []

        url = self.request.get('url')
        width = int(self.request.get('sizeU'))
        height = int(self.request.get('sizeV'))
        sceneName = self.request.get('sceneName')
        polyNames = self.request.get('polyNames').split(';')
        amosId = self.request.get('amosId')
        createSc = self.request.get('createSc')
        go_to = self.request.get('goToAfterSave') #where to redirect
        private = self.request.get('is_private') #is the scene private? True or False

        # process the input
        for i in range(len(imageUs)):
            tempImageUs = imageUs[i].split()
            tempImageVs = imageVs[i].split()
            tempLatitudes = latitudes[i].split()
            tempLongitudes = longitudes[i].split()
            tempAltitudes = altitudes[i].split()

            allImageUs.append( [ int(j) for j in tempImageUs ] )
            allImageVs.append( [ int(j) for j in tempImageVs ] )
            allLatitudes.append( [ float(j) for j in tempLatitudes ] )
            allLongitudes.append( [ float(j) for j in tempLongitudes ] )
            allAltitudes.append( [ float(j) for j in tempAltitudes ] )

        for i in range(len(triangleIndices)):
            tempTriangleIndices = triangleIndices[i].split()
            allTriangleIndices.append( [ int(j) for j in tempTriangleIndices ] )

        if private == "True":
            is_private = True
        elif private == "False":
            is_private = False
        else:
            is_private = None
        
        if amosId:
            amosId = int(amosId)
        
        sceneId = self.request.get('sceneId')
        scene = None

        # grab the scene or make a new one.
        if sceneId != '':
            scene = Scene.get_by_key_name('scene' + sceneId)
        
        if not scene:
            # make a new scene.  First, we have to get the current webcam image.
            firstImage = None
            try:
                # spoof the header so that it looks like this request is coming from a browser.
                req = urllib2.Request(url, headers={'User-Agent':
                    r'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.10) Gecko/20100504 Firefox/3.5.10'})
                result = urllib2.urlopen(req)
                imageContents = result.read()
                firstImage = db.Blob(imageContents)
            except urllib2.URLError, e:
                # if we can't read it, route to the intro page.
                values = {
                    'message' : 'Couldn''t read url: ' + url,
                    'username' : username,
                    'logInURL' :logInURL,
                    'logOutURL' :logOutURL
                }
                self.response.out.write(template.render(TEMPLATE_DIRECTORY + 'middle.html', values))
                return
            if is_private != None:
                scene = addScene(url=url,
                                 firstImage=firstImage,
                                 width=width,
                                 height=height,
                                 is_private=is_private)
            else:
                scene = addScene(url=url,
                                 firstImage=firstImage,
                                 width=width,
                                 height=height,
                                 is_private=False)
            if user:
                scene.owner = user;
                scene.put()
            memcache.delete("allScenes")
        
        if not sceneName:
            sceneName = 'Scene '+str(scene.index)
        
        if sceneName != '' and not scene.name:
            scene.name = sceneName
            scene.put()

        if amosId and not scene.amosId:
            scene.amosId = amosId
            scene.put()

        allMeshes = Mesh.all().filter('scene = ', scene)
        numMeshes = allMeshes.count()

        # for every polygon
        for p in range(len(allImageUs)):
            # get the polygon name
            if polyNames[p] == 'none' or polyNames[p] == '':
                polyName = 'Polygon ' + str(numMeshes)
                numMeshes = numMeshes + 1
            else:
                polyName = polyNames[p]

            # save each point in the current polygon
            correspondenceIDs = []
            correspondences = []

            for i in range(len(allImageUs[p])):
                corr = addCorrespondence(scene   = scene,
                                  latitude   = allLatitudes[p][i],
                                  longitude  = allLongitudes[p][i],
                                  altitude   = allAltitudes[p][i],
                                  u          = allImageUs[p][i],
                                  v          = allImageVs[p][i])

                if user:
                    corr.owner = user;
                    corr.put()
                 
                correspondenceIDs.append(corr.index)
                correspondences.append(corr)

            if not scene.cameraLatitude :
                scene.cameraLatitude = allLatitudes[p][0]
                scene.cameraLongitude = allLongitudes[p][0]
                scene.put()

            noPoints = len(allImageUs[p])

            if len(correspondences) > 1:
                # write the mesh file.
                originLat, originLon, originAlt, \
                daePositions, daeNormals, daeUVs, daeTriangles, \
                nPositions, nNormals, nUVs, nTriangles = \
                    common.meshwriter.writeMeshFile(correspondences, allTriangleIndices[p], width, height)

                #print str(nTriangles)+"";
                    
                poly = addMesh(scene = scene,
                               name  = polyName,
                               points = noPoints,
                               triangles = allTriangleIndices[p],
                               correspondenceMapping = correspondenceIDs,
                               daePositionArray = daePositions,
                               daeNormalArray = daeNormals,
                               daeUVArray = daeUVs,
                               daeTriangles = daeTriangles,
                               originLatitude = originLat,
                               originLongitude = originLon,
                               originAltitude = originAlt,
                               nPositions = nPositions,
                               nNormals = nNormals,
                               nUVs = nUVs,
                               nTriangles = nTriangles)
                if user:
                    poly.owner = user
                    poly.put()

        # end for all polygons
           
        calibrate.calibrateCamera(scene)
        memcache.delete("allScenes")
        
        if go_to=='1':
            self.redirect("/viewScene?scene=" + str(scene.index))
        elif go_to=='2':
            self.redirect("/build?scene="+ str(scene.index))
        else:
            print "Error!"
    